#include <iostream>
#include <map>
#include <fstream>

#include <boost/tr1/memory.hpp>

#include "Repository.h"
#include "../classes_teste/Estatistica.h"
#include "../classes_outros/Config.h"
#include "../classes_dados/Hasher.h"
#include "../classes_dados/Hasher.h"
#include "../classes_dados/ThreadFunctionDatabase.h"

#include <ctime>
#include <cstdio>

using namespace std;

std::tr1::shared_ptr<Repository> Repository::theRepository(new Repository());
boost::mutex Repository::storeMutex;
//boost::mutex Repository::readHashFileMutex;

int Repository::numStores = 0;
unsigned long int Repository::contador = 0;



Repository::Repository(){
	contadorPaginas.setFile(Config::getPageCountFileName());
}

Repository::~Repository(){
//	fclose(outHashFile);
}


void Repository::newOldStore(string _url, string _page){
	ofstream fileToDisk;
	if(_url == "") return;  // elimina string vazia
	try{
	
		string hash = Hasher::stringHash64FromString(_url);
		string folder;
		
		folder = "./disco/" + hash.substr(0,2);
		folder = folder + "/" + hash;
		
		//cout << "Folder:  Repository::newOldStore    " << folder << endl;
		
		fileToDisk.open(folder.c_str());
		
		if ( (fileToDisk.rdstate() & ifstream::eofbit ) != 0 )	cout << "Error opening eof\n";
		if ( (fileToDisk.rdstate() & ifstream::failbit ) != 0 )	 cout << "Error opening fail\n";
		if ( (fileToDisk.rdstate() & ifstream::badbit ) != 0 )   cout << "Error opening bad\n";
		if ( (fileToDisk.rdstate() & ifstream::goodbit ) != 0 ) 	cout << "Error opening good\n";
		
		if(fileToDisk.fail()){
			cout << "numFalhasOpen: " << numStores << endl;
			cout << "hash: " << hash.c_str() << endl;
			//cout << "_page.c_str(): " << _page.c_str() << endl;
			cout << "_page.size() " << _page.size() << endl;
			fileToDisk.clear();
			return;
		}
		
		fileToDisk.write(_page.c_str(), _page.size());	
		
		if(fileToDisk.fail()){
			cout << "numFalhasWrite: " << numStores << endl;
			cout << "hash: " << hash.c_str() << endl;
			//cout << "_page.c_str(): " << _page.c_str() << endl;
			cout << "_page.size() " << _page.size() << endl;
			cout << endl;
			fileToDisk.clear();
			return;
		}
		
		fileToDisk.close();	
	
	}catch(...){
		cout << "Algo no Repository::newOldStore deu errado... " << endl;
	}
}



void Repository::store(string _url, string _page){
	newOldStore(_url, _page);
	
//  dados estatisticos de paginas copiadas
    time_t timeMc;
    time(&timeMc);
    contador++;
    if(( contador % 500) == 1){
    	contadorPaginas.addData((unsigned long int) timeMc, contador);
    }
    
    if(contador >= 10000000){
    	ThreadFunctionDatabase::setSyncLifeThread(0); // acaobou
    	cout << " Total de 10.000.000 !!!!" << endl;
    }
    
	return;
}

bool Repository::isEmpty(string hash){
	  it = mapa.find(hash);
	  if( it == mapa.end() ) return true;
	  else                   return false;
}

int Repository::size(){
	return (unsigned int) mapa.size();
}

string Repository::getPage(string _url){
	string hash = Hasher::stringHash64FromString(_url);
	if(!isEmpty(hash)) return mapa[hash];
	else return "";
}








